/*
 * Copyright (C) 2013  Richard Schilling. All rights reserved.
 * contact: coderroadie@gmail.com
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package android.persist.op.sqlite;

import java.math.BigDecimal;
import java.math.BigInteger;

import android.persist.PersistException;

/**
 * {@code SQLiteType} defines SQL data types that are currently supported. These
 * are the basic storage classes supported by SQLite. The type of BLOB is not
 * included because it is not yet supported.
 * 
 * @author Richard Schilling (coderroadie@gmail.com)
 * @since 1.0s
 */
public enum SQLiteType {

    /**
     * This is mapped to the following SQLite types: INT INTEGER TINYINT
     * SMALLINT MEDIUMINT BIGINT UNSIGNED BIG INT INT2 INT8
     */
    INTEGER,

    /**
     * This is mapped to the following SQLite types: CHARACTER(20) VARCHAR(255)
     * VARYING CHARACTER(255) NCHAR(55) NATIVE CHARACTER(70) NVARCHAR(100) TEXT
     * CLOB
     */
    TEXT,

    BLOB,

    /**
     * This is mapped to the following SQLite types: REAL DOUBLE DOUBLE
     * PRECISION FLOAT
     */
    REAL,

    /**
     * This is mapped to the following SQLite types: NUMERIC DECIMAL(10,5)
     * BOOLEAN DATE DATETIME
     */
    NUMERIC, ;

    /**
     * Determines the SQLite type for a given class. If the function throws a
     * {@link PersistException} then the class will be treated as a foreign
     * reference class.
     * 
     * @param clazz the type to check.
     * @return the SQLite type that this class is stored as.
     * @since 1.0
     * @throws PersistException if the specified class does not have an
     *             associated type that it can be saved to.
     */
    public static SQLiteType sqlType(Class<?> clazz) {

        if (clazz == byte[].class || clazz == Byte[].class) {
            return BLOB;
        }

        if (clazz == short[].class || clazz == Short[].class) {
            return BLOB;
        }
        if (clazz == int[].class || clazz == Integer[].class) {
            return BLOB;
        }
        if (clazz == long[].class || clazz == Long[].class) {
            return BLOB;
        }
        if (clazz == float[].class || clazz == Float[].class) {
            return BLOB;
        }
        if (clazz == double[].class || clazz == Double[].class) {
            return BLOB;
        }
        if (clazz == boolean[].class || clazz == Boolean[].class) {
            return BLOB;
        }
        if (clazz == char[].class || clazz == Character[].class) {
            return BLOB;
        }

        if (clazz == byte.class || clazz == Byte.class) {
            return INTEGER;
        }

        if (clazz == short.class || clazz == Short.class) {
            return INTEGER;
        }

        if (clazz == int.class || clazz == Integer.class) {
            return INTEGER;
        }

        if (clazz == long.class || clazz == Long.class) {
            return INTEGER;
        }

        if (clazz == float.class || clazz == Float.class) {
            return REAL;
        }

        if (clazz == double.class || clazz == Double.class) {
            return REAL;
        }

        if (clazz == boolean.class || clazz == Boolean.class) {
            return NUMERIC;
        }

        if (clazz == char.class || clazz == Character.class) {
            return TEXT;
        }

        if (clazz == String.class) {
            return TEXT;
        }

        if (clazz == BigDecimal.class) {
            return REAL;
        }

        if (clazz == BigInteger.class) {
            return TEXT;
        }

        throw new PersistException("unable to determine SQLite type");

    }

}
